using System;
using HarmonyLib;
using Helpers;
using MarriageFertility.Helpers;
using MarriageFertility.Mcm;
using MarriageFertility.Texts;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.GameComponents;

namespace MarriageFertility.Patches;

// 定义婚姻相关的补丁类
public static class MarryPatch
{
    // 为 Hero 类的 Spouse 属性设置方法添加 Harmony 补丁
    [HarmonyPatch(typeof(Hero), "Spouse", MethodType.Setter)]
    public static class SpouseSetterPatch
    {
        // 前缀方法，拦截对 Spouse 属性的设置
        public static bool Prefix(Hero __instance, Hero value)
        {
            // 获取当前实例的 _spouse 字段值
            Traverse instanceTraverse = Traverse.Create(__instance);
            Hero currentSpouse = instanceTraverse.Field<Hero>("_spouse").Value;

            // 如果当前配偶与传入值相同，则直接返回 false，取消原方法调用
            if (currentSpouse == value)
                return false;

            // 更新当前实例的配偶字段值
            instanceTraverse.Field<Hero>("_spouse").Value = value;

            // 如果当前实例已经有配偶，将其添加到前配偶列表中
            if (currentSpouse != null)
            {
                Traverse exSpousesTraverse = instanceTraverse.Field("_exSpouses");
                exSpousesTraverse.Method("Add", currentSpouse).GetValue();
            }

            // 如果新配偶为 null，则返回 false，取消后续操作
            if (__instance.Spouse == null)
                return false;

            // 确保新配偶的 Spouse 属性也指向当前实例
            __instance.Spouse.Spouse = __instance;

            // 返回 false，取消原方法调用
            return false;
        }
    }

    // 为 MarriageAction 的 ApplyInternal 方法添加 Harmony 补丁
    [HarmonyPatch(typeof(MarriageAction), "ApplyInternal")]
    public static class MarriageActionPatch
    {
        // 前缀方法，用于修改婚姻逻辑
        public static bool Prefix(Hero firstHero, Hero secondHero, bool showNotification)
        {
            try
            {
                // 验证两个角色是否可以结婚
                if (IsValidHeroPair(firstHero, secondHero))
                {
                    // 删除旧配偶关系
                    DeleteOldSpouse(firstHero, secondHero);

                    // 处理婚姻相关逻辑
                    ProcessHeroPair(firstHero, secondHero);

                    // 返回 false，取消原方法调用
                    return false;
                }
            }
            catch (Exception e)
            {
                // 捕获异常并记录错误信息
                Log.ErrorMessage(e.Message);
            }

            // 如果验证未通过，继续执行原方法
            return true;
        }

        // 验证两个角色是否符合结婚条件
        private static bool IsValidHeroPair(Hero firstHero, Hero secondHero)
        {
            return firstHero.Clan == Clan.PlayerClan || secondHero.Clan == Clan.PlayerClan;
        }

        // 删除旧配偶关系
        private static void DeleteOldSpouse(Hero firstHero, Hero secondHero)
        {
            if (firstHero.Clan == Clan.PlayerClan)
            {
                secondHero.Spouse = null;
            }
            else
            {
                firstHero.Spouse = null;
            }
        }

        // 处理两个角色的婚姻逻辑
        private static void ProcessHeroPair(Hero firstHero, Hero secondHero)
        {
            try
            {
                // 如果两个角色都没有家族，记录错误信息并返回
                if (firstHero.Clan == null && secondHero.Clan == null)
                {
                    Log.ErrorMessage(MessageText.NoClansMarriageError);
                    return;
                }

                if (secondHero.IsPrisoner)
                {
                    EndCaptivityAction.ApplyByReleasedByChoice(secondHero);
                }
                
                // 确定玩家角色和其他角色
                DeterminePlayerAndOtherHero(firstHero, secondHero, out Hero playerHero, out Hero otherHero);

                // 判断是否需要加入玩家家族
                bool shouldJoinPlayerClan = firstHero == Hero.MainHero || secondHero == Hero.MainHero ||
                                            MCMSettings.Instance.JoinPlayerClan;

        

                // 如果其他角色是流浪者，将其转变为同伴
                if (otherHero.IsWanderer)
                {
                    ChangeWandererToCompanion(otherHero);
                }

                // 在完成所有逻辑后处理婚姻关系
                MarryOne(playerHero, otherHero, true);
                
                if (shouldJoinPlayerClan)
                {
                    // 让其他角色加入玩家家族
                    ClanHelper.LordJoinPlayerClan(otherHero);
                }
            }
            catch (Exception ex)
            {
                // 捕获并记录异常
                Log.ErrorMessage("ProcessHeroPair error: " + ex.Message);
                
            }
        }

        // 确定玩家角色和其他角色
        private static void DeterminePlayerAndOtherHero(Hero firstHero, Hero secondHero, out Hero playerHero,
            out Hero otherHero)
        {
            if (firstHero.Clan == null)
            {
                firstHero.Clan = secondHero.Clan;
                playerHero = secondHero;
                otherHero = firstHero;
            }
            else if (secondHero.Clan == null)
            {
                secondHero.Clan = firstHero.Clan;
                playerHero = firstHero;
                otherHero = secondHero;
            }
            else
            {
                playerHero = firstHero.Clan == Clan.PlayerClan ? firstHero : secondHero;
                otherHero = playerHero == firstHero ? secondHero : firstHero;
            }
        }

        // 将流浪者转变为同伴
        private static void ChangeWandererToCompanion(Hero wanderer)
        {
            if (Clan.PlayerClan != null)
            {
                Helper.ChangeCompanionOccupation(wanderer);
                wanderer.Clan = Clan.PlayerClan;
                if (!Clan.PlayerClan.Heroes.Contains(wanderer))
                    Clan.PlayerClan.Heroes.Add(wanderer);
            }
            else
            {
                Log.ErrorMessage(MessageText.PlayerClanEmptyError);
            }
        }

        // 后缀方法，清理旧的配偶关系
        private static void Postfix(Hero firstHero, Hero secondHero)
        {
            firstHero.ExSpouses?.Remove(secondHero);
            secondHero.ExSpouses?.Remove(firstHero);
            if (firstHero == Hero.MainHero)
                secondHero.ExSpouses?.Clear();
            else if (secondHero == Hero.MainHero)
                firstHero.ExSpouses?.Clear();
        }

        // 处理婚姻关系
        private static void MarryOne(Hero firstHero, Hero secondHero, bool showNotification)
        {
            try
            {
                // 设置双方为彼此的配偶
                firstHero.Spouse = secondHero;
                secondHero.Spouse = firstHero;

                // 修改双方的关系值
                var relationChange =
                    Campaign.Current.Models.MarriageModel.GetEffectiveRelationIncrease(firstHero, secondHero);
                ChangeRelationAction.ApplyRelationChangeBetweenHeroes(firstHero, secondHero, relationChange, false);
                
                if(firstHero.Clan != secondHero.Clan)
                {
                    Clan clanAfterMarriage =
                        Campaign.Current.Models.MarriageModel.GetClanAfterMarriage(firstHero, secondHero);
                    if (firstHero.Clan != clanAfterMarriage)
                        HandleClanChangeAfterMarriageForHero(firstHero, clanAfterMarriage);
                    else
                        HandleClanChangeAfterMarriageForHero(secondHero, clanAfterMarriage);
                }

                // 更新恋爱状态为已婚
                ChangeRomanticStateAction.Apply(firstHero, secondHero, Romance.RomanceLevelEnum.Marriage);

                // 触发婚姻事件通知
                CampaignEventDispatcher.Instance.OnHeroesMarried(firstHero, secondHero, showNotification);
            }
            catch (Exception e)
            {
                // 捕获并记录异常
                Log.ErrorMessage(e.StackTrace);
                Log.ErrorMessage(e.Message);
            }
        }

        // 处理婚姻后角色的家族变更
        private static void HandleClanChangeAfterMarriageForHero(Hero hero, Clan clanAfterMarriage)
        {
            Clan clan = hero.Clan;

            // 移除角色的治理者身份
            if (hero.GovernorOf != null)
                ChangeGovernorAction.RemoveGovernorOf(hero);

            // 如果角色属于某个队伍，则进行相应处理
            if (hero.PartyBelongedTo != null)
            {
                if (clan.Kingdom != clanAfterMarriage.Kingdom)
                {
                    if (hero.PartyBelongedTo.Army != null)
                    {
                        if (hero.PartyBelongedTo.Army.LeaderParty == hero.PartyBelongedTo)
                            DisbandArmyAction.ApplyByUnknownReason(hero.PartyBelongedTo.Army);
                        else
                            hero.PartyBelongedTo.Army = null;
                    }

                    FactionHelper.FinishAllRelatedHostileActionsOfNobleToFaction(hero,
                        (IFaction)clanAfterMarriage.Kingdom ?? clanAfterMarriage);
                }

                MakeHeroFugitiveAction.Apply(hero);
            }

            // 更新角色的家族
            hero.Clan = clanAfterMarriage;

            // 更新角色的家乡据点
            foreach (Hero hero1 in clan.Heroes)
                hero1.UpdateHomeSettlement();
            foreach (Hero hero2 in clanAfterMarriage.Heroes)
                hero2.UpdateHomeSettlement();
        }
    }

    // 为 DefaultDiplomacyModel 的 GetHeroesForEffectiveRelation 方法添加 Harmony 补丁
    [HarmonyPatch(typeof(DefaultDiplomacyModel), "GetHeroesForEffectiveRelation")]
    public static class GetHeroesForEffectiveRelationPatch
    {
        // 前缀方法，用于修改有效关系计算逻辑
        public static bool Prefix(Hero hero1,
            Hero hero2,
            out Hero effectiveHero1,
            out Hero effectiveHero2)
        {
            effectiveHero1 = hero1;
            effectiveHero2 = hero2;

            // 如果未启用个性化关系选项，则继续执行原方法
            if (!MCMSettings.Instance.PersonRelation) return true;

            // 如果两个角色不是玩家的同伴或玩家角色，则返回 false，取消原方法调用
            if (effectiveHero1 != effectiveHero2 &&
                (!hero1.IsPlayerCompanion || !hero2.IsHumanPlayerCharacter) &&
                (!hero1.IsPlayerCompanion || !hero2.IsHumanPlayerCharacter))
                return false;

            effectiveHero1 = hero1;
            effectiveHero2 = hero2;

            // 返回 false，取消原方法调用
            return false;
        }
    }
}
